home *** CD-ROM | disk | FTP | other *** search
/ Aminet 39 / Aminet 39 (2000)(Schatztruhe)[!][Oct 2000].iso / Aminet / util / misc / cookietool.lha / cookietool / strstuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-25  |  6.1 KB  |  233 lines

  1. /*
  2.     (c) 1995-2000 by Wilhelm Noeker (wnoeker@t-online.de)
  3.  
  4.     This program is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU General Public License as
  6.     published by the Free Software Foundation; either version 2 of the
  7.     License, or (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful, but
  10.     WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12.     General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  17.     02111-1307 USA
  18.     
  19.  */
  20.  
  21. /*========================================================================*\
  22.  |  File: strstuff.c                                   Date: 20 Sep 1997  |
  23.  *------------------------------------------------------------------------*
  24.  |   Some string functions, similar to those from the standard library    |
  25.  |                  in <string.h>, but more flexible.                     |
  26.  |   You must call str_setup() before using any of these functions !!!    |
  27.  |                                                                        |
  28. \*========================================================================*/
  29.  
  30. #include <stddef.h>
  31. #include <stdio.h>
  32. #include "strstuff.h"
  33.  
  34. UBYTE to_upper[ 256 ];            /* conversion table */
  35. int   is_space[ 256 ];            /* lookup table */
  36. int bordermode, case_sense;
  37.  
  38.  
  39.  
  40. /*
  41.  * Set up a to_upper[] table that can convert all national characters from
  42.  * the ISO 8859-1/ECMA 94 charset to uppercase, not only 'a'-'z'.
  43.  * Depending on the global variable <case_sense> this table may just as 
  44.  * well do nothing at all.  
  45.  * Similarly, the is_space[] table which is built here may call anything 
  46.  * but alphanumerics a 'space', depending on the setting of <bordermode>.
  47.  */
  48. void str_setup( int bm, int cs )
  49. {  
  50.   int c, d;
  51.  
  52.   bordermode = bm;
  53.   case_sense = cs;              /* set global variables */
  54.   for( c = 0; c < 256; c++ )
  55.     {
  56.       to_upper[ c ] = c;
  57.       is_space[ c ] = ( bordermode < 2 || (c & 0x7f) <= ' ' );
  58.     }
  59.   for( c = 'a'; c <= 'z'; c++ )
  60.     {
  61.       d = c + 'A' - 'a';
  62.       to_upper[ c ] = d;
  63.       is_space[ c ] = 0;
  64.       is_space[ d ] = 0;
  65.     }
  66.   for( c = '0'; c <= '9'; c++ )
  67.     {
  68.       is_space[ c ] = 0;
  69.     }
  70.   for( c = 224; c < 256; c++ )
  71.     if( c != 247 )
  72.       {                         /* 247 is the division sign -:- */
  73.         d = c - 32;
  74.         is_space[ c ] = 0;
  75.         is_space[ d ] = 0;
  76.         if( c != 255 )          /* and don't convert '"y' to 'ss' : ) */
  77.           to_upper[ c ] = d;
  78.       }
  79.   if( case_sense )              /* destroy the to_upper[] table again */
  80.     for( c = 0; c < 256; c++ )
  81.       to_upper[ c ] = c;
  82.   is_space[ 0 ] = 0;            /* important, will be taken advantage of! */
  83. }
  84.  
  85.  
  86.  
  87. /* 
  88.  * str_cmp() will work like strcmp() if( case_sense && bordermode == 3 ),
  89.  * but can change its behaviour depending on those variables.
  90.  * Will also indicate by special (but legal) return values if <s> was an
  91.  * abbreviation of <t> or vice versa.
  92.  */
  93. int str_cmp( UBYTE *s, UBYTE *t )
  94. {
  95.   if( bordermode < 3 )
  96.     {                           /* modes where number of 'spaces' doesn't count */
  97.       while( is_space[ *s ] )
  98.         s++;                    /* advance to first word */
  99.       while( is_space[ *t ] )
  100.         t++;
  101.       while( to_upper[ *s ] == to_upper[ *t ] )
  102.         {
  103.           if( *s == '\0' )
  104.             return 0;
  105.           s++;
  106.           t++;
  107.           if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
  108.             {
  109.               /* both at the end of a word OR in sloppy bordermode */
  110.               while( is_space[ *s ] )
  111.                 s++;            /* skip the spaces */
  112.               while( is_space[ *t ] )
  113.                 t++;
  114.             }
  115.         }
  116.     }
  117.   else
  118.     {
  119.       while( to_upper[ *s ] == to_upper[ *t ] )
  120.         {
  121.           if( *s == '\0' )
  122.             return 0;
  123.           s++;
  124.           t++;
  125.         }
  126.     }
  127.   if( *s == '\0' )
  128.     return STR_SHORTER;
  129.   else if( *t == '\0' )
  130.     return STR_LONGER;
  131.   else
  132.     return( to_upper[ *s ] - to_upper[ *t ] );
  133. }
  134.  
  135.  
  136.  
  137. /* 
  138.  * The same as str_cmp(), but will only compare up to <n> characters.
  139.  * (Only two lines of code are different.)
  140.  */
  141. int strn_cmp( UBYTE *s, UBYTE *t, size_t n )
  142. {
  143.   if( bordermode < 3 )
  144.     {
  145.       while( is_space[ *s ] )
  146.         s++;
  147.       while( is_space[ *t ] )
  148.         t++;
  149.       while( to_upper[ *s ] == to_upper[ *t ] )
  150.         {
  151.           if( --n == 0 || *s == '\0' )
  152.             return 0;           /* that's the difference */
  153.           s++;
  154.           t++;
  155.           if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
  156.             {
  157.               while( is_space[ *s ] )
  158.                 s++;
  159.               while( is_space[ *t ] )
  160.                 t++;
  161.             }
  162.         }
  163.     }
  164.   else
  165.     {
  166.       while( to_upper[ *s ] == to_upper[ *t ] )
  167.         {
  168.           if( --n == 0 || *s == '\0' )
  169.             return 0;           /* and here once more */
  170.           s++;
  171.           t++;
  172.         }
  173.     }
  174.   if( *s == '\0' )
  175.     return STR_SHORTER;
  176.   else if( *t == '\0' )
  177.     return STR_LONGER;
  178.   else
  179.     return( to_upper[ *s ] - to_upper[ *t ] );
  180. }
  181.  
  182.  
  183.  
  184. /* 
  185.  * Find a copy of t in s, like strstr( )does.
  186.  * Note that bordermode has NO effect here!
  187.  */
  188. UBYTE *str_str( UBYTE *s, UBYTE *t )           
  189. {
  190.   int c;
  191.  
  192.   while( *s )
  193.     {
  194.       c = str_cmp( s, t );
  195.       if( c == 0 || c == STR_LONGER )
  196.         return s;
  197.       s++;
  198.     }
  199.   return NULL;
  200. }
  201.  
  202.  
  203.  
  204. /* 
  205.  * Some user info printed to <stdout>.
  206.  */
  207. void print_strstat( void )
  208. {
  209.   printf( "string processing:\n" );
  210.   printf( "  upper-/lowercase: " );
  211.   if( case_sense )
  212.     printf( "strict\n" );
  213.   else
  214.     printf( "'ABC'='abc'\n" );
  215.   printf( "  word delimiters:  " );
  216.   switch( bordermode )
  217.     {
  218.     case 0:
  219.       printf( "'a,b c'='abc'\n" );
  220.       break;
  221.     case 1:
  222.       printf( "'a, b, c'='a,b c'\n" );
  223.       break;
  224.     case 2:
  225.       printf( "'a  b  c'='a b c'\n" );
  226.       break;
  227.     case 3:
  228.       printf( "strict\n" );
  229.       break;
  230.     }
  231. }
  232.  
  233.